package messageAPI.RabbitMQIntegration;

//import java.util.Arrays;
//import java.util.List;
//import java.util.Map;

import java.io.IOException;

import com.rabbitmq.client.MessageProperties;

import messageAPI.Core.IDistributedCommunicationHandler;

/**
 * The Class RabbitMQHandler.
 */
public class RabbitMQHandler extends RabbitMQBase implements IDistributedCommunicationHandler {

	protected RabbitMQHandler() {
		super();
    }

    private static RabbitMQHandler instance = null;

    public static RabbitMQHandler getInstance() {
        if(instance == null) {
            instance = new RabbitMQHandler();
        }
        return instance;
    }


	/**
	 * Send message (default implementation).
	 *
	 * @param category the category
	 * @param textMessage the text message
	 */
	public void sendMessageDefault(String category, String textMessage)
	{
		byte[] message = textMessage.getBytes();
		RoutingKey = category;

		try
		{
            RabbitChannel.queueBind(QUEUE_NAME, ExchangeName, RoutingKey);

			RabbitChannel.queueDeclare(QUEUE_NAME, false, false, false, null);

            //RabbitChannel.basicPublish("", QUEUE_NAME, null, textMessage.getBytes());

            RabbitChannel.basicPublish(ExchangeName, category, null, message);

			RabbitChannel.waitForConfirmsOrDie();
		}
		catch(Exception exception)
		{
			//must build better ex handling
		}
	}

	/**
	 * Send message publish confirm method.
	 *
	 * @param category the category
	 * @param textMessage the text message
	 * @throws Throwable the throwable
	 */
	public void sendMessagePublishConfirmMethod(String category, String textMessage) throws Throwable
	{
		byte[] message = textMessage.getBytes();
		RoutingKey = category;

		//long startTime = System.currentTimeMillis();

		// Setup

		RabbitChannel.queueBind(QUEUE_NAME, ExchangeName, RoutingKey);

		RabbitChannel.queueDeclare(QUEUE_NAME, false, false, false, null);
		RabbitChannel.confirmSelect();

		// Publish
        //RabbitChannel.basicPublish("", QUEUE_NAME, null, textMessage.getBytes()); //getBytes()
        //RabbitChannel.basicPublish("", QUEUE_NAME, null, message);

		RabbitChannel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_BASIC, message);


		RabbitChannel.waitForConfirmsOrDie();

		//long endTime = System.currentTimeMillis();
		//System.out.printf("Test took %.3fs\n", (float)(endTime - startTime)/1000);
		//    } catch (Throwable e) {
		//        System.out.println("foobar :(");
		//        System.out.print(e);
		//    }
	}


	/* (non-Javadoc)
	 * @see messageAPI.Core.IDistributedCommunicationHandler#SendMessage(java.lang.String, java.lang.String)
	 */
	public void sendMessage(String category, String textMessage)
	{
		try {
            //sendMessageDefault(category, textMessage);
			sendMessagePublishConfirmMethod(category, textMessage);
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//SendMessageDefault(category, textMessage);
	}

    public void shutDownHandler()
    {
        try {
            System.out.println(" [MessageAPITest] Shutting down test.");

            if(RabbitChannel.isOpen())
            {
                RabbitChannel.close();
            }

            if(RabbitConnection.isOpen())
            {
                RabbitConnection.close();
            }

            System.out.println(" [MessageAPITest] Shut down completed.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}